﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

using DBMS.Models;
using DBMS.Models.DataInterfaces;
using DBMS.Data;
using DBMS.Helpers.Application;
using DBMS.Helpers.Metadata;

namespace DBMS.Controllers
{
    public class TablesController : Controller
    {
        private ITableRepository tableRepository;
        private IDatabaseRepository databaseRepository;
        private IColumnRepository columnRepository;
        private IValueRepository valueRepository;

        public TablesController()
        {
            this.databaseRepository = new DatabaseRepository();
            this.tableRepository = new TableRepository();
            this.columnRepository = new ColumnRepository();
            this.valueRepository = new ValueRepository();
        }


        public ActionResult Index(string databaseId, string databaseName)
        {
            Database database = databaseRepository.GetDatabase(Int32.Parse(databaseId));

            if (database != null)
            {
                IList<Table> tables = tableRepository.GetAllTablesForDatabase(database.Index);

                ViewBag.Database = database;
                ViewBag.Tables = tables;

                return PartialView();
            }
            else
            {
                return RedirectToAction("Error", "Errors", new { errorMessage = "Database could not be found."});
            }
        }

        public ActionResult Menu()
        {
            return PartialView();
        }

        public ActionResult CreateTable(string databaseId, string databaseName)
        {
            Database database = databaseRepository.GetDatabase(Int32.Parse(databaseId));
            ViewBag.Database = database;

            return PartialView();
        }

        [HttpPost]
        public ActionResult CreateTable(string databaseId, string databaseName, Table table)
        {
            try
            {
                Database database = databaseRepository.GetDatabase(Int32.Parse(databaseId));
                tableRepository.Create(database, table);
                return RedirectToAction("Index", "Tables", new { databaseId = database.Index, databaseName = databaseName });
            }
            catch (Exception e)
            {
                return RedirectToAction("Error", "Errors", new { errorMessage = e.Message });
            }
            
            
        }

        public ActionResult BrowseTable(string databaseId, string tableId)
        {
            Database database = databaseRepository.GetDatabase(Int32.Parse(databaseId));
            Table table = tableRepository.GetTable(database.Index, Int32.Parse(tableId));

            IList<Column> columns = columnRepository.GetAllColumnsForTable(database.Index, table.Index);
            IList<Value> values = valueRepository.GetValuesForTable(database.Index, table.Index);

            ViewBag.Database = database;
            ViewBag.Table = table;

            ViewBag.Columns = columns;
            ViewBag.Values = values;
            ViewBag.RowIds = values.Select(x => x.RowId).Distinct().ToList();

            return View(values);
        }

        public ActionResult EditTable(string databaseId, string tableId)
        {
            Database database = databaseRepository.GetDatabase(Int32.Parse(databaseId));
            Table table = tableRepository.GetTable(database.Index, Int32.Parse(tableId));

            ViewBag.Database = database;

            return View(table);
        }

        [HttpPost]
        public ActionResult EditTable(string databaseId, Table table)
        {
            Database database = databaseRepository.GetDatabase(Int32.Parse(databaseId));

            tableRepository.Update(database, table);

            return RedirectToAction("Index", new {databaseId = databaseId });
        }

        public ActionResult DropTable(string databaseId, string tableId)
        {
            Database db = databaseRepository.GetDatabase(Convert.ToInt32(databaseId));
            int idTable = Convert.ToInt32(tableId);

            foreach (Table table in db.Tables)
            {
                if (table.Index == idTable)
                {
                    tableRepository.Delete(db.Index, table.Index);
                    return RedirectToAction("Index", "Tables", 
                        new { databaseId = db.Index, databaseName = db.Name });
                }
            }

            return RedirectToAction("Index", "Errors", 
                        new { errorMessage = "The table with index " + tableId + " was not found" });
        }

        private void TransformValuesToTable(Table table, Database database, string tableName)
        {
            table.Database = database;
            table.Name = tableName;
        }
    }
}
